import { createSlice, createAsyncThunk, PayloadAction } from '@reduxjs/toolkit';
import { settingsService } from '@/services/settings';

export interface AppSettings {
  // General settings
  theme: 'light' | 'dark' | 'system';
  language: string;
  autoSave: boolean;
  autoUpdate: boolean;
  startMinimized: boolean;
  minimizeToTray: boolean;

  // Video processing settings
  defaultOutputFormat: string;
  defaultQuality: 'low' | 'medium' | 'high' | 'lossless';
  maxConcurrentTasks: number;
  processingPriority: 'low' | 'normal' | 'high';
  tempDirectory: string;

  // Output settings
  defaultOutputPath: string;
  fileNamingPattern: string;
  overwriteExisting: boolean;
  preserveMetadata: boolean;
  createSubfolders: boolean;

  // Advanced settings
  ffmpegPath?: string;
  enableHardwareAcceleration: boolean;
  maxMemoryUsage: number; // in MB
  logLevel: 'error' | 'warn' | 'info' | 'debug';
  enableTelemetry: boolean;

  // UI settings
  sidebarCollapsed: boolean;
  showProcessingDetails: boolean;
  showThumbnails: boolean;
  gridViewMode: 'grid' | 'list';

  // Notification settings
  showDesktopNotifications: boolean;
  playCompletionSound: boolean;
  notifyOnError: boolean;
  notifyOnCompletion: boolean;
}

interface SettingsState {
  settings: AppSettings;
  isLoading: boolean;
  error: string | null;
  isDirty: boolean; // Has unsaved changes
}

const defaultSettings: AppSettings = {
  // General
  theme: 'system',
  language: 'en',
  autoSave: true,
  autoUpdate: true,
  startMinimized: false,
  minimizeToTray: false,

  // Video processing
  defaultOutputFormat: 'mp4',
  defaultQuality: 'high',
  maxConcurrentTasks: 2,
  processingPriority: 'normal',
  tempDirectory: '',

  // Output
  defaultOutputPath: '',
  fileNamingPattern: '{name}_processed.{ext}',
  overwriteExisting: false,
  preserveMetadata: true,
  createSubfolders: false,

  // Advanced
  enableHardwareAcceleration: true,
  maxMemoryUsage: 2048,
  logLevel: 'info',
  enableTelemetry: true,

  // UI
  sidebarCollapsed: false,
  showProcessingDetails: true,
  showThumbnails: true,
  gridViewMode: 'grid',

  // Notifications
  showDesktopNotifications: true,
  playCompletionSound: true,
  notifyOnError: true,
  notifyOnCompletion: true,
};

const initialState: SettingsState = {
  settings: defaultSettings,
  isLoading: false,
  error: null,
  isDirty: false,
};

// Async thunks
export const loadSettings = createAsyncThunk('settings/load', async (_, { rejectWithValue }) => {
  try {
    const response = await settingsService.getAll();
    if (response.success) {
      return { ...defaultSettings, ...response.data };
    }
    return rejectWithValue(response.error || 'Failed to load settings');
  } catch (error) {
    return rejectWithValue(error instanceof Error ? error.message : 'Failed to load settings');
  }
});

export const saveSettings = createAsyncThunk(
  'settings/save',
  async (settings: Partial<AppSettings>, { rejectWithValue, getState }) => {
    try {
      const state = getState() as { settings: SettingsState };
      const updatedSettings = { ...state.settings.settings, ...settings };

      // Save each setting individually
      for (const [key, value] of Object.entries(updatedSettings)) {
        await settingsService.set(key, value);
      }

      return updatedSettings;
    } catch (error) {
      return rejectWithValue(error instanceof Error ? error.message : 'Failed to save settings');
    }
  }
);

export const resetSettings = createAsyncThunk('settings/reset', async (_, { rejectWithValue }) => {
  try {
    await settingsService.clear();

    // Save default settings
    for (const [key, value] of Object.entries(defaultSettings)) {
      await settingsService.set(key, value);
    }

    return defaultSettings;
  } catch (error) {
    return rejectWithValue(error instanceof Error ? error.message : 'Failed to reset settings');
  }
});

export const exportSettings = createAsyncThunk(
  'settings/export',
  async (filePath: string, { rejectWithValue }) => {
    try {
      await settingsService.export(filePath);
    } catch (error) {
      return rejectWithValue(error instanceof Error ? error.message : 'Failed to export settings');
    }
  }
);

export const importSettings = createAsyncThunk(
  'settings/import',
  async (filePath: string, { rejectWithValue }) => {
    try {
      await settingsService.import(filePath);
      const response = await settingsService.getAll();
      if (response.success) {
        return { ...defaultSettings, ...response.data };
      }
      return rejectWithValue(response.error || 'Failed to import settings');
    } catch (error) {
      return rejectWithValue(error instanceof Error ? error.message : 'Failed to import settings');
    }
  }
);

// Settings slice
const settingsSlice = createSlice({
  name: 'settings',
  initialState,
  reducers: {
    updateSetting: <K extends keyof AppSettings>(
      state: SettingsState,
      action: PayloadAction<{ key: K; value: AppSettings[K] }>
    ) => {
      const { key, value } = action.payload;
      state.settings[key] = value;
      state.isDirty = true;
    },
    updateSettings: (state, action: PayloadAction<Partial<AppSettings>>) => {
      state.settings = { ...state.settings, ...action.payload };
      state.isDirty = true;
    },
    clearError: state => {
      state.error = null;
    },
    markClean: state => {
      state.isDirty = false;
    },
  },
  extraReducers: builder => {
    // Load settings
    builder
      .addCase(loadSettings.pending, state => {
        state.isLoading = true;
        state.error = null;
      })
      .addCase(loadSettings.fulfilled, (state, action) => {
        state.isLoading = false;
        state.settings = action.payload;
        state.isDirty = false;
      })
      .addCase(loadSettings.rejected, (state, action) => {
        state.isLoading = false;
        state.error = action.payload as string;
      });

    // Save settings
    builder
      .addCase(saveSettings.pending, state => {
        state.isLoading = true;
        state.error = null;
      })
      .addCase(saveSettings.fulfilled, (state, action) => {
        state.isLoading = false;
        state.settings = action.payload;
        state.isDirty = false;
      })
      .addCase(saveSettings.rejected, (state, action) => {
        state.isLoading = false;
        state.error = action.payload as string;
      });

    // Reset settings
    builder
      .addCase(resetSettings.pending, state => {
        state.isLoading = true;
        state.error = null;
      })
      .addCase(resetSettings.fulfilled, (state, action) => {
        state.isLoading = false;
        state.settings = action.payload;
        state.isDirty = false;
      })
      .addCase(resetSettings.rejected, (state, action) => {
        state.isLoading = false;
        state.error = action.payload as string;
      });

    // Export settings
    builder
      .addCase(exportSettings.pending, state => {
        state.isLoading = true;
        state.error = null;
      })
      .addCase(exportSettings.fulfilled, state => {
        state.isLoading = false;
      })
      .addCase(exportSettings.rejected, (state, action) => {
        state.isLoading = false;
        state.error = action.payload as string;
      });

    // Import settings
    builder
      .addCase(importSettings.pending, state => {
        state.isLoading = true;
        state.error = null;
      })
      .addCase(importSettings.fulfilled, (state, action) => {
        state.isLoading = false;
        state.settings = action.payload;
        state.isDirty = false;
      })
      .addCase(importSettings.rejected, (state, action) => {
        state.isLoading = false;
        state.error = action.payload as string;
      });
  },
});

export const { updateSetting, updateSettings, clearError, markClean } = settingsSlice.actions;
export default settingsSlice.reducer;
